<!--
 * @Author: liucong19
 * @Date: 2021-07-16 18:45:51
 * @LastEditTime: 2021-07-22 09:29:21
 * @LastEditors: liucong19
 * @Description: 播放 FLV 流
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>播放 FLV 流</title>
  <style>
    .wrapper {display: flex; justify-content: center;}
    .video-container {display: flex; flex-direction: column; justify-content: center; align-items: center;}
    .video-info {width: 800px; list-style: none;}
  </style>
</head>
<body>
  <p>FLV(Flash Video)是一种网络视频格式，FLV 只能基于 flash 播放，要在 HTML5 的 video 标签中播放 Flv 格式的视频流可以使用开源库 flv.js。</p>
  <p>flv.js 将视频的 flv 流并实时转换为 fmp4 格式，再通过 Media Source Extension 喂给浏览器的 video 标签。</p>
  <a href="https://github.com/bilibili/flv.js/blob/master/docs/api.md"  target="_blank">flv.js</a>

  <div class="wrapper">
    <div class="video-container">
      <video id="video" width="800" height="450" controls muted></video>
      <p>
        <button id="play">播放/暂停</button>
        <button id="muted">静音开关</button>
        <button id="setVolume">播放音量</button>
        <button id="fast">快进2秒</button>
        <button id="setRate">2倍速度播放</button>
      </p>
    </div>
    <ul id="info" class="video-info">
      <li>
        <span>视频地址：</span><span class="currentSrc"></span>
      </li>
      <li>
        <span>视频总时长：</span><span class="duration"></span>
      </li>
      <li>
        <span>当前时间点：</span><span class="currentTime"></span>
      </li>
      <li>
        <span>是否暂停：</span><span class="isPaused"></span>
      </li>
      <li>
        <span>是否静音：</span><span class="isMuted"></span>
      </li>
      <li>
        <span>播放音量：</span><span class="volume"></span>
      </li>
      <li>
        <span>播放速率：</span><span class="playbackRate"></span>
      </li>
      <li>
        <span>帧率：</span><span class="fps"></span>
      </li>
      <li>
        <span>丢帧数：</span><span class="droppedFrames"></span>
      </li>
      <li>
        <span>渲染帧数：</span><span class="decodedFrames"></span>
      </li>
    </ul>
  </div>

  <script src="lib/flv.js"></script> 
  <script type="module">
    // IE11 不支持 import / export 语法
    import sources from './sources.js'

    // 获取 video 标签
    let video = document.querySelector('#video')
    let flvPlayer = null

    // rtmp 直播流必须转成 http-flv 协议才能播放
    let flvUrl = sources.flv[0]

    if (flvjs.isSupported()) {
      // 根据不同的视频类型创建不同的实例
      flvPlayer = flvjs.createPlayer({
        // 视频类型 flv or mp4
        type: 'flv',
        // 是否为实时流
        isLive: true,
        // 必须是 http/https 或者 ws/wss
        url: flvUrl
      })
      // 绑定元素
      flvPlayer.attachMediaElement(video)

      // 加载视频源
      flvPlayer.load()

      // 播放 video标签设置静音（muted）才能自动播放，否则需要手动点击才能播放
      flvPlayer.play()

      // 监听事件
      flvPlayer.on(flvjs.Events.LOADING_COMPLETE, () => {
        console.log('LOADING_COMPLETE :>> ', flvPlayer);
      })
      // 监听媒体技术信息
      flvPlayer.on(flvjs.Events.MEDIA_INFO, () => {
        let mediaInfo = flvPlayer.mediaInfo
        info.querySelector('.fps').innerText = mediaInfo.fps
      })
      // 监听统计信息
      flvPlayer.on(flvjs.Events.STATISTICS_INFO, () => {
        let statisticsInfo = flvPlayer.statisticsInfo
      })
    }

    /* ---------------- video 标签原生方法 ---------------- */

    // 播放/暂停
    document.querySelector('#play').addEventListener('click', (e) => {
      if (video.paused) {
        video.play()
      } else {
        video.pause()
      }
    })

    // 静音开关
    document.querySelector('#muted').addEventListener('click', (e) => {
      if (!video.muted) {
        video.muted = true
      } else {
        video.muted = false
      }
      info.querySelector('.isMuted').innerText = video.muted
    })

    // 设置音量 [0, 1]
    document.querySelector('#setVolume').addEventListener('click', (e) => {
      let volume = video.volume * 100
      volume -= 1
      video.volume = Math.round(volume) / 100
    })

    // 快进/后退
    document.querySelector('#fast').addEventListener('click', (e) => {
      video.currentTime += 2
    })

    // 播放速率
    document.querySelector('#setRate').addEventListener('click', (e) => {
      video.playbackRate = 2
    })

    /* ---------------- video 标签原生事件 ---------------- */

    // 视频可以播放时触发
    video.oncanplay = (e) => {
      info.querySelector('.duration').innerText = video.duration
      info.querySelector('.currentTime').innerText = video.currentTime
      info.querySelector('.isPaused').innerText = video.paused
      info.querySelector('.isMuted').innerText = video.muted
      info.querySelector('.volume').innerText = video.volume * 100
      info.querySelector('.playbackRate').innerText = video.playbackRate
    }

    // 监听播放
    video.onplay = (e) => {
      console.log('play')
      info.querySelector('.isPaused').innerText = video.paused
    }

    // 监听暂停
    video.onpause = (e) => {
      console.log('pause')
      info.querySelector('.isPaused').innerText = video.paused
    }

    // 监听音量
    video.onvolumechange = (e) => {
      console.log('音量: >> ', video.volume)
      info.querySelector('.volume').innerText = video.volume * 100
    }

    // 播放进度改变时触发
    video.ontimeupdate = (e) => {
      info.querySelector('.currentTime').innerText = video.currentTime
      
      let statisticsInfo = flvPlayer.statisticsInfo
      console.log('STATISTICS_INFO :>> ', statisticsInfo);
      info.querySelector('.decodedFrames').innerText = statisticsInfo.decodedFrames
      info.querySelector('.droppedFrames').innerText = statisticsInfo.droppedFrames
      info.querySelector('.currentSrc').innerText = statisticsInfo.url
    }

    // 播放速度
    video.onratechange = (e) => {
      info.querySelector('.playbackRate').innerText = video.playbackRate
    }

  </script> 
</body>
</html>
